from fastapi import FastAPI, HTTPException, Depends, Body
from fastapi.staticfiles import StaticFiles
from fastapi.responses import RedirectResponse, FileResponse
from sqlalchemy.orm import Session
from . import models, database
from pydantic import BaseModel
from typing import Dict, List
import logging
from datetime import datetime
from pathlib import Path
from sqlalchemy import Column, Integer, Boolean, DateTime
from sqlalchemy import func

# 添加全局变量用于存储题目和答案
questions = []  # 存储当前活动的题目
answers = []    # 存储学生的答案

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

app = FastAPI()

# 获取项目根目录
BASE_DIR = Path(__file__).parent.parent

# 挂载静态文件目录
app.mount("/static", StaticFiles(directory=str(BASE_DIR / "static")), name="static")


# 创建数据库表
models.Base.metadata.create_all(bind=database.engine)

# 添加请求模型
class ScoreCreate(BaseModel):
    group_id: str
    score: int
    score_type: str

# 添加新的请求模型
class StudentCreate(BaseModel):
    name: str
    group_id: str

# 添加请求模型
class QuestionCreate(BaseModel):
    content: str
    option_a: str
    option_b: str
    option_c: str
    option_d: str

class AnswerSubmit(BaseModel):
    question_id: int
    answer: str
    student_name: str
    group_id: str

# 添加新的数据模型
class QuestionBatch(BaseModel):
    questions: List[dict]

class AnswerBatch(BaseModel):
    answers: List[dict]

class CorrectAnswerUpdate(BaseModel):
    correct_answer: str  # A, B, C, D

class CorrectAnswersBatch(BaseModel):
    answers: List[dict]  # [{"question_id": int, "correct_answer": str}]

# 根路由重定向到index.html
@app.get("/")
async def root():
    return RedirectResponse(url="/static/index.html")

# 提交评分
@app.post("/api/scores")
async def submit_score(
    score_data: ScoreCreate,
    db: Session = Depends(database.get_db)
):
    try:
        if score_data.score < 1 or score_data.score > 5:
            raise HTTPException(status_code=400, detail="评分必须在1-5之间")
            
        new_score = models.Score(
            group_id=score_data.group_id,
            score=score_data.score,
            type=models.ScoreType(score_data.score_type)
        )
        db.add(new_score)
        db.commit()
        logger.info(f"新评分提交成功: {score_data.group_id} - {score_data.score}星 ({score_data.score_type})")
        return {"message": "评分提交成功"}
    except Exception as e:
        logger.error(f"提交评分失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail="提交评分失败")

# 添加新的API端点
@app.post("/api/students")
async def create_student(
    student_data: StudentCreate,
    db: Session = Depends(database.get_db)
):
    try:
        # 检查同一小组是否已存在同名学生
        existing_student = db.query(models.Student).filter(
            models.Student.group_id == student_data.group_id,
            models.Student.name == student_data.name
        ).first()
        
        if existing_student:
            # 如果存在同名学生，直接返回成功
            logger.info(f"学生已存在: {student_data.name} 在 {student_data.group_id}")
            return {"message": "学生信息提交成功"}
        
        # 如果不存在同名学生，创建新记录
        new_student = models.Student(
            name=student_data.name,
            group_id=student_data.group_id
        )
        db.add(new_student)
        db.commit()
        logger.info(f"新学生添加成功: {student_data.name} 在 {student_data.group_id}")
        return {"message": "学生信息提交成功"}
        
    except Exception as e:
        logger.error(f"提交学生信息失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail="提交学生信息失败")

# 获取最新评分
@app.get("/api/scores/latest")

async def get_latest_scores(db: Session = Depends(database.get_db)):
    try:
        # 获取每个小组的最新教师评分和学生自评
        latest_scores = {}
        for group_id in [f"group{i}" for i in range(1, 9)]:  # 8个小组
            scores = {
                "teacher": None,
                "student": None
            }
            
            # 获取最新的教师评分
            teacher_score = db.query(models.Score).filter(
                models.Score.group_id == group_id,
                models.Score.type == models.ScoreType.TEACHER
            ).order_by(models.Score.created_at.desc()).first()
            
            if teacher_score:
                scores["teacher"] = teacher_score.score
                
            # 获取最新的学生自评
            student_score = db.query(models.Score).filter(
                models.Score.group_id == group_id,
                models.Score.type == models.ScoreType.STUDENT
            ).order_by(models.Score.created_at.desc()).first()
            
            if student_score:
                scores["student"] = student_score.score
                
            latest_scores[group_id] = scores
            
        return latest_scores
    except Exception as e:
        logger.error(f"获取最新评分失败: {e}")
        raise HTTPException(status_code=500, detail="获取评分失败")

# 获取历史记录
@app.get("/api/scores/history/{group_id}")

async def get_score_history(group_id: str, db: Session = Depends(database.get_db)):
    try:
        scores = db.query(models.Score).filter(
            models.Score.group_id == group_id
        ).order_by(models.Score.created_at.desc()).all()
        
        return [
            {
                "group_id": score.group_id,
                "score": score.score,
                "type": score.type.value,
                "created_at": score.created_at.isoformat()
            }
            for score in scores
        ]
    except Exception as e:
        logger.error(f"获取历史记录失败: {e}")
        raise HTTPException(status_code=500, detail="获取历史记录失败")

# 获取学生总数
@app.get("/api/students/count")
async def get_student_count(db: Session = Depends(database.get_db)):
    try:
        count = db.query(models.Student).count()
        logger.info(f"当前学生总数: {count}")
        return {"count": count}
    except Exception as e:
        logger.error(f"获取学生人数失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 获取小组成员
@app.get("/api/students/{group_id}")
async def get_group_students(group_id: str, db: Session = Depends(database.get_db)):
    try:
        students = db.query(models.Student).filter(
            models.Student.group_id == group_id
        ).all()
        return [
            {
                "id": student.id,
                "name": student.name,
                "group_id": student.group_id
            }
            for student in students
        ]
    except Exception as e:
        logger.error(f"获取小组成员失败: {e}")
        raise HTTPException(status_code=500, detail="获取小组成员失败")

# 删除学生
@app.delete("/api/students/{group_id}/{student_name}")
async def delete_student(
    group_id: str,
    student_name: str,
    db: Session = Depends(database.get_db)
):
    try:
        # 首先找到学生
        student = db.query(models.Student).filter(
            models.Student.name == student_name,
            models.Student.group_id == group_id
        ).first()
        
        if not student:
            raise HTTPException(status_code=404, detail="学生不存在")
            
        # 先删除该学生的所有答案记录
        db.query(models.StudentAnswer).filter(
            models.StudentAnswer.student_id == student.id
        ).delete()
        
        # 然后删除学生
        db.query(models.Student).filter(
            models.Student.id == student.id
        ).delete()
        
        db.commit()
        logger.info(f"成功删除学生: {student_name} 从 {group_id}")
        return {"message": "删除成功"}
        
    except Exception as e:
        logger.error(f"删除学生失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail="删除学生失败")

# 修改开始上课的路由
@app.post("/api/class/start")
async def start_class(db: Session = Depends(database.get_db)):
    try:
        # 将之前的会话设为非活动
        db.query(models.ClassSession).filter(
            models.ClassSession.is_active == True
        ).update({"is_active": False})
        
        # 创建新的会话
        new_session = models.ClassSession(is_active=True)
        db.add(new_session)
        
        # 将所有题目设为非活动（只影响显示，不删除数据）
        db.query(models.Question).filter(
            models.Question.is_active == True
        ).update({"is_active": False})
        
        db.commit()
        db.refresh(new_session)
        
        return {"message": "新课程已开始", "session_id": new_session.id}
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 获取课堂状态的API端点
@app.get("/api/class/status")
async def get_class_status(db: Session = Depends(database.get_db)):
    try:
        status = db.query(models.ClassStatus).first()
        return {
            "is_active": bool(status and status.is_active),
            "started_at": status.started_at if status else None
        }
    except Exception as e:
        logger.error(f"获取课堂状态失败: {e}")
        raise HTTPException(status_code=500, detail="获取课堂状态失败")

# 创建选择题
@app.post("/api/questions")
async def create_question(
    question_data: QuestionCreate,
    db: Session = Depends(database.get_db)
):
    try:
        # 将之前的题目设为非活动
        db.query(models.Question).filter(models.Question.is_active == True).update(
            {"is_active": False}
        )
        
        # 创建新题目
        new_question = models.Question(
            content=question_data.content,
            option_a=question_data.option_a,
            option_b=question_data.option_b,
            option_c=question_data.option_c,
            option_d=question_data.option_d,
            is_active=True
        )
        db.add(new_question)
        db.commit()
        db.refresh(new_question)
        
        return {"id": new_question.id}
    except Exception as e:
        logger.error(f"创建题目失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail="创建题目失败")

# 获取当前活动的题目
@app.get("/api/questions/active")
async def get_active_questions(db: Session = Depends(database.get_db)):
    try:
        questions = db.query(models.Question).filter(
            models.Question.is_active == True
        ).order_by(models.Question.question_number).all()
        
        return [
            {
                "id": q.id,
                "question_number": q.question_number,  # 确保返回题号
                "content": q.content,
                "option_a": q.option_a,
                "option_b": q.option_b,
                "option_c": q.option_c,
                "option_d": q.option_d
            }
            for q in questions
        ]
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 提交答案
@app.post("/api/answers")
async def submit_answer(
    answer_data: AnswerSubmit,
    db: Session = Depends(database.get_db)
):
    try:
        # 获取学生信息
        student = db.query(models.Student).filter(
            models.Student.name == answer_data.student_name,
            models.Student.group_id == answer_data.group_id
        ).first()
        
        if not student:
            raise HTTPException(status_code=404, detail="学生不存在")
            
        # 检查是否已经回答过
        existing_answer = db.query(models.StudentAnswer).filter(
            models.StudentAnswer.student_id == student.id,
            models.StudentAnswer.question_id == answer_data.question_id
        ).first()
        
        if existing_answer:
            # 如果已经回答过，更新答案
            existing_answer.answer = answer_data.answer
            existing_answer.submitted_at = datetime.now()
        else:
            # 如果是新答案，创建新记录
            new_answer = models.StudentAnswer(
                student_id=student.id,
                question_id=answer_data.question_id,
                answer=answer_data.answer
            )
            db.add(new_answer)
            
        db.commit()
        logger.info(f"学生 {answer_data.student_name} 提交答案成功")
        return {"message": "答案提交成功"}
        
    except Exception as e:
        logger.error(f"提交答案失败: {e}")
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 获取学生答案
@app.get("/api/answers/{question_id}")
async def get_question_answers(question_id: int, db: Session = Depends(database.get_db)):
    try:
        # 获取题目的正确答案
        question = db.query(models.Question).filter(models.Question.id == question_id).first()
        if not question:
            raise HTTPException(status_code=404, detail="题目不存在")

        # 获取所有学生对这道题的答案
        answers = db.query(models.StudentAnswer).filter(
            models.StudentAnswer.question_id == question_id
        ).all()

        # 转换为包含正确性判断的响应格式
        result = []
        for answer in answers:
            # 获取学生信息
            student = db.query(models.Student).filter(
                models.Student.id == answer.student_id
            ).first()
            
            if student:
                # 判断答案是否正确
                is_correct = False
                if question.correct_answer:  # 如果已设置正确答案
                    is_correct = answer.answer == question.correct_answer

                result.append({
                    "name": student.name,
                    "group_id": student.group_id,
                    "answer": answer.answer,
                    "is_correct": is_correct,  # 添加正确性判断
                    "submitted_at": answer.submitted_at
                })

        return result
    except Exception as e:
        logger.error(f"获取答案失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

# 修改批量创建题目的路由
@app.post("/api/questions/batch")
async def create_questions_batch(question_batch: QuestionBatch, db: Session = Depends(database.get_db)):
    try:
        # 获取当前活动的会话
        active_session = db.query(models.ClassSession).filter(
            models.ClassSession.is_active == True
        ).first()
        
        if not active_session:
            # 如果没有活动会话，创建一个新会话
            active_session = models.ClassSession(is_active=True)
            db.add(active_session)
            db.commit()
            db.refresh(active_session)
        
        # 获取当前会话中已有的题目数量
        current_questions_count = db.query(models.Question).filter(
            models.Question.session_id == active_session.id
        ).count()
        
        # 将之前的题目设为非活动（只影响显示）
        db.query(models.Question).filter(
            models.Question.is_active == True
        ).update({"is_active": False})
        
        # 批量添加新题目
        new_questions = []
        for i, q in enumerate(question_batch.questions):
            new_question = models.Question(
                session_id=active_session.id,
                question_number=current_questions_count + i + 1,
                content=f"第{current_questions_count + i + 1}题",
                option_a=q["option_a"],
                option_b=q["option_b"],
                option_c=q["option_c"],
                option_d=q["option_d"],
                is_active=True
            )
            db.add(new_question)
            new_questions.append(new_question)
        
        try:
            db.commit()
        except Exception as e:
            logger.error(f"Error committing questions: {str(e)}")
            db.rollback()
            raise
            
        return {"message": f"Successfully created {len(question_batch.questions)} questions"}
    except Exception as e:
        logger.error(f"Error in create_questions_batch: {str(e)}")
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 修改批量提交答案的路由
@app.post("/api/answers/batch")
async def submit_answers_batch(answer_batch: AnswerBatch, db: Session = Depends(database.get_db)):
    try:
        for answer in answer_batch.answers:
            # 获取学生信息
            student = db.query(models.Student).filter(
                models.Student.name == answer["student_name"],
                models.Student.group_id == answer["group_id"]
            ).first()
            
            if not student:
                logger.error(f"Student not found: {answer['student_name']} in group {answer['group_id']}")
                continue  # 跳过不存在的学生，继续处理其他答案
            
            try:
                # 检查是否已经回答过
                existing_answer = db.query(models.StudentAnswer).filter(
                    models.StudentAnswer.student_id == student.id,
                    models.StudentAnswer.question_id == answer["question_id"]
                ).first()
                
                if existing_answer:
                    # 更新已有答案
                    existing_answer.answer = answer["answer"]
                    existing_answer.submitted_at = datetime.now()
                else:
                    # 创建新答案
                    new_answer = models.StudentAnswer(
                        student_id=student.id,
                        question_id=answer["question_id"],
                        answer=answer["answer"],
                        is_correct=False  # 默认设置为False，等待教师设置正确答案后更新
                    )
                    db.add(new_answer)
                
                logger.info(f"Answer processed for student {student.name}, question {answer['question_id']}")
            except Exception as e:
                logger.error(f"Error processing answer: {str(e)}")
                continue  # 跳过出错的答案，继续处理其他答案
        
        db.commit()
        return {"message": f"Successfully submitted {len(answer_batch.answers)} answers"}
    except Exception as e:
        logger.error(f"Batch answer submission failed: {str(e)}")
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 添加获取所有题目的路由
@app.get("/api/questions/all")
async def get_all_questions(db: Session = Depends(database.get_db)):
    try:
        # 获取所有题目，按创建时间排序
        questions = db.query(models.Question).order_by(models.Question.created_at).all()
        
        # 为每个题目添加序号
        question_list = []
        for i, q in enumerate(questions):
            question_list.append({
                "id": q.id,
                "content": q.content,
                "options": {
                    "A": q.option_a,
                    "B": q.option_b,
                    "C": q.option_c,
                    "D": q.option_d
                },
                "question_number": i + 1,  # 添加题号
                "is_active": q.is_active
            })
            
        return question_list
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 添加清空所有题目和答案的路由
@app.post("/api/questions/clear")
async def clear_all_questions(db: Session = Depends(database.get_db)):
    try:
        # 删除所有答案
        db.query(models.StudentAnswer).delete()
        
        # 删除所有题目
        db.query(models.Question).delete()
        
        db.commit()
        return {"message": "Successfully cleared all questions and answers"}
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 添加获取学生历史答题记录的路由
@app.get("/api/student/history/{student_name}")
async def get_student_history(student_name: str, db: Session = Depends(database.get_db)):
    try:
        # 获取学生的所有答题记录，按会话和题号排序
        answers = db.query(
            models.Question.session_id,
            models.Question.question_number,
            models.Question.content,
            models.StudentAnswer.answer,
            models.ClassSession.started_at
        ).join(
            models.StudentAnswer,
            models.Question.id == models.StudentAnswer.question_id
        ).join(
            models.Student,
            models.StudentAnswer.student_id == models.Student.id
        ).join(
            models.ClassSession,
            models.Question.session_id == models.ClassSession.id
        ).filter(
            models.Student.name == student_name
        ).order_by(
            models.ClassSession.started_at.desc(),
            models.Question.question_number
        ).all()
        
        # 组织返回数据
        sessions = {}
        for session_id, question_number, content, answer, started_at in answers:
            if session_id not in sessions:
                sessions[session_id] = {
                    "started_at": started_at.strftime("%Y-%m-%d %H:%M:%S"),
                    "answers": []
                }
            sessions[session_id]["answers"].append({
                "question_number": question_number,
                "content": content,
                "answer": answer
            })
        
        return sessions
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 设置正确答案
@app.put("/api/questions/{question_id}/correct-answer")
async def set_correct_answer(
    question_id: int,
    answer_data: CorrectAnswerUpdate,
    db: Session = Depends(database.get_db)
):
    try:
        # 更新题目的正确答案
        question = db.query(models.Question).filter(
            models.Question.id == question_id
        ).first()
        
        if not question:
            raise HTTPException(status_code=404, detail="题目不存在")
            
        question.correct_answer = answer_data.correct_answer
        
        # 更新所有相关答案的正确性
        answers = db.query(models.StudentAnswer).filter(
            models.StudentAnswer.question_id == question_id
        ).all()
        
        for answer in answers:
            answer.is_correct = (answer.answer == answer_data.correct_answer)
        
        db.commit()
        return {"message": "正确答案设置成功"}
        
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

# 设置正确答案批量
@app.put("/api/questions/correct-answers/batch")
async def set_correct_answers(
    answers: dict = Body(...),  # {"answers": [{"question_id": int, "correct_answer": str}]}
    db: Session = Depends(database.get_db)
):
    try:
        for answer_data in answers.get("answers", []):
            question_id = answer_data.get("question_id")
            correct_answer = answer_data.get("correct_answer")
            
            if not question_id or not correct_answer:
                continue
                
            # 更新题目的正确答案
            question = db.query(models.Question).filter(
                models.Question.id == question_id
            ).first()
            
            if question:
                question.correct_answer = correct_answer
                
                # 更新所有已提交答案的正确性
                student_answers = db.query(models.StudentAnswer).filter(
                    models.StudentAnswer.question_id == question_id
                ).all()
                
                for student_answer in student_answers:
                    student_answer.is_correct = (student_answer.answer == correct_answer)
        
        db.commit()
        return {"message": "正确答案设置成功"}
    except Exception as e:
        db.rollback()
        logger.error(f"设置正确答案失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))